use std::fmt::Debug;

use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename = "service", rename_all = "lowercase")]
pub struct Head {
    #[serde(rename = "sys-header")]
    pub sys: SysHead,
    #[serde(rename = "app-header")]
    pub app: AppHead,
    #[serde(rename = "local-header")]
    pub local: LocalHead,
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename = "struct")]
pub struct Ret {
    #[serde(rename(serialize = "RET_CODE,string,6,0", deserialize = "RET_CODE"))]
    pub code: Option<String>,
    #[serde(rename(serialize = "RET_MSG,string,256,0", deserialize = "RET_MSG"))]
    pub msg: Option<String>,
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename = "SYS_HEAD")]
pub struct SysHead {
    #[serde(rename(serialize = "SERVER_ID,string,30,0", deserialize = "SERVER_ID"))]
    pub server_id: Option<String>,
    #[serde(rename(serialize = "SERVICE_CODE,string,24,0", deserialize = "SERVICE_CODE"))]
    pub service_code: Option<String>,
    #[serde(rename(serialize = "MESSAGE_TYPE,string,2,0", deserialize = "MESSAGE_TYPE"))]
    pub message_type: Option<String>,
    #[serde(rename(serialize = "USER_ID,string,30,0", deserialize = "USER_ID"))]
    pub user_id: Option<String>,
    #[serde(rename(
        serialize = "TRAN_TIMESTAMP,string,9,0",
        deserialize = "TRAN_TIMESTAMP"
    ))]
    pub tran_timestamp: Option<String>,
    #[serde(rename(serialize = "CONSUMER_ID,string,2,0", deserialize = "CONSUMER_ID"))]
    pub consumer_id: Option<String>,
    #[serde(rename(serialize = "WS_ID,string,30,0", deserialize = "WS_ID"))]
    pub ws_id: Option<String>,
    #[serde(rename(serialize = "SEQ_NO,string,20,0", deserialize = "SEQ_NO"))]
    pub seq_no: Option<String>,
    #[serde(rename(serialize = "TRAN_MODE,string,10,0", deserialize = "TRAN_MODE"))]
    pub tran_mode: Option<String>,
    #[serde(rename(serialize = "SOURCE_TYPE,string,2,0", deserialize = "SOURCE_TYPE"))]
    pub source_type: Option<String>,
    #[serde(rename(serialize = "USER_LANG,string,7,0", deserialize = "USER_LANG"))]
    pub user_lang: Option<String>,
    #[serde(rename(serialize = "MESSAGE_CODE,string,6,0", deserialize = "MESSAGE_CODE"))]
    pub message_code: Option<String>,
    #[serde(rename(serialize = "MODULE_ID,string,2,0", deserialize = "MODULE_ID"))]
    pub module_id: Option<String>,
    #[serde(rename(serialize = "TRAN_DATE,string,8,0", deserialize = "TRAN_DATE"))]
    pub tran_date: Option<String>,
    #[serde(rename(serialize = "BRANCH_ID,string,6,0", deserialize = "BRANCH_ID"))]
    pub branch_id: Option<String>,
    #[serde(rename(serialize = "TRAN_CODE,string,8,0", deserialize = "TRAN_CODE"))]
    pub tran_code: Option<String>,
    #[serde(rename(
        serialize = "SOURCE_BRANCH_NO,string,40,0",
        deserialize = "SOURCE_BRANCH_NO"
    ))]
    pub source_branch_no: Option<String>,
    #[serde(rename(
        serialize = "DEST_BRANCH_NO,string,40,0",
        deserialize = "DEST_BRANCH_NO"
    ))]
    pub dest_branch_no: Option<String>,
    #[serde(rename(serialize = "CUSTOMER_ID,string,12,0", deserialize = "CUSTOMER_ID"))]
    pub customer_id: Option<String>,
    #[serde(rename(serialize = "RET_STATUS,string,1,0", deserialize = "RET_STATUS"))]
    pub ret_status: Option<String>,
    #[serde(rename = "RET")]
    pub ret: Option<Vec<Ret>>,
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename = "APP_HEAD", rename_all = "UPPERCASE")]
pub struct AppHead {
    #[serde(rename(serialize = "PGUP_OR_PGDN,string,1,0", deserialize = "PGUP_OR_PGDN"))]
    pub page_up_down: Option<String>,
    #[serde(rename(serialize = "TOTAL_NUM,string,12,0", deserialize = "TOTAL_NUM"))]
    pub total_num: Option<String>,
    #[serde(rename(serialize = "CURRENT_NUM,string,12,0", deserialize = "CURRENT_NUM"))]
    pub current_num: Option<String>,
    #[serde(rename(serialize = "PAGE_START,string,12,0", deserialize = "PAGE_START"))]
    pub page_start: Option<String>,
    #[serde(rename(serialize = "PAGE_END,string,12,0", deserialize = "PAGE_END"))]
    pub page_end: Option<String>,
    #[serde(rename(serialize = "TOTAL_ROWS,string,12,0", deserialize = "TOTAL_ROWS"))]
    pub total_rows: Option<String>,
    #[serde(rename(serialize = "TOTAL_PAGES,string,12,0", deserialize = "TOTAL_PAGES"))]
    pub total_pages: Option<String>,
    #[serde(rename(serialize = "TOTAL_FLAG,string,1,0", deserialize = "TOTAL_FLAG"))]
    pub total_flag: Option<String>,
    #[serde(rename(serialize = "APPR_FLAG,string,1,0", deserialize = "APPR_FLAG"))]
    pub approve_flag: Option<String>,
    #[serde(rename(serialize = "APPR_USER_ID,string,30,0", deserialize = "APPR_USER_ID"))]
    pub approve_user_id: Option<String>,
    #[serde(rename(serialize = "AUTH_FLAG,string,1,0", deserialize = "AUTH_FLAG"))]
    pub auth_flag: Option<String>,
    #[serde(rename(serialize = "AUTH_USER_ID,string,30,0", deserialize = "AUTH_USER_ID"))]
    pub auth_user_id: Option<String>,
    #[serde(rename(serialize = "FILE_PATH,string,512,0", deserialize = "FILE_PATH"))]
    pub file_path: Option<String>,
    #[serde(rename(serialize = "PROGRAM_ID,string,8,0", deserialize = "PROGRAM_ID"))]
    pub program_id: Option<String>,
    #[serde(rename(
        serialize = "REVERSAL_TRAN_TYPE,string,4,0",
        deserialize = "REVERSAL_TRAN_TYPE"
    ))]
    pub reversal_tran_type: Option<String>,
    #[serde(rename(serialize = "TRAN_TYPE,string,4,0", deserialize = "TRAN_TYPE"))]
    pub tran_type: Option<String>,
    #[serde(rename(
        serialize = "OPERATION_CODE,string,8,0",
        deserialize = "OPERATION_CODE"
    ))]
    pub operation_code: Option<String>,
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename = "LOCAL_HEAD")]
pub struct LocalHead {
    #[serde(rename = "RET")]
    pub ret: Option<Vec<Ret>>,
}
